/*!
 * \file WtRtRunner.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 *
 * \brief
 */
#pragma once
#include <string>

#include "PorterDefs.h"

#include "../Includes/IDataReader.h"
#include "../Includes/ILogHandler.h"

#include "../WtCore/ActionPolicyMgr.h"
#include "../WtCore/CtaStrategyMgr.h"
#include "../WtCore/EventNotifier.h"
#include "../WtCore/ParserAdapter.h"
#include "../WtCore/TraderAdapter.h"
#include "../WtCore/WtArbiExecuter.h"
#include "../WtCore/WtCtaEngine.h"
#include "../WtCore/WtDiffExecuter.h"
#include "../WtCore/WtDistExecuter.h"
#include "../WtCore/WtDtMgr.h"
#include "../WtCore/WtLocalExecuter.h"

#include "../WTSTools/WTSBaseDataMgr.h"
#include "../WTSTools/WTSHotMgr.h"

NS_WTP_BEGIN
class WTSVariant;
class WtDataStorage;
NS_WTP_END

USING_NS_WTP;

typedef enum tagEngineType {
    ET_CTA = 999, // CTA引擎
    ET_HFT,       //高频引擎
    ET_SEL        //选股引擎
} EngineType;

class WtRtRunner : public IEngineEvtListener,
                   public ILogHandler,
                   public IHisDataLoader {
public:
    WtRtRunner();
    ~WtRtRunner();

public:
    //////////////////////////////////////////////////////////////////////////
    // IBtDataLoader
    virtual bool loadFinalHisBars(void* obj, const char* stdCode,
                                  WTSKlinePeriod period,
                                  FuncReadBars cb) override;

    virtual bool loadRawHisBars(void* obj, const char* stdCode,
                                WTSKlinePeriod period,
                                FuncReadBars cb) override;

    virtual bool loadAllAdjFactors(void* obj, FuncReadFactors cb) override;

    virtual bool loadAdjFactors(void* obj, const char* stdCode,
                                FuncReadFactors cb) override;

    void feedRawBars(WTSBarStruct* bars, uint32_t count);

    void feedAdjFactors(const char* stdCode, uint32_t* dates, double* factors,
                        uint32_t count);

public:
    /*
     *	初始化
     */
    bool init(const char* logCfg = "logcfg.prop", bool isFile = true,
              const char* genDir = "");

    bool config(const char* cfgFile, bool isFile = true);

    void run(bool bAsync = false);

    void release();

    void registerCtaCallbacks(FuncStraInitCallback cbInit,
                              FuncStraTickCallback cbTick,
                              FuncStraCalcCallback cbCalc,
                              FuncStraBarCallback cbBar,
                              FuncSessionEvtCallback cbSessEvt,
                              FuncStraCondTriggerCallback cbCondTrigger = NULL);

    void registerEvtCallback(FuncEventCallback cbEvt);

    void registerParserPorter(FuncParserEvtCallback cbEvt,
                              FuncParserSubCallback cbSub);

    void registerExecuterPorter(FuncExecInitCallback cbInit,
                                FuncExecCmdCallback cbExec);

    void registerExtDataLoader(FuncLoadFnlBars fnlBarLoader,
                               FuncLoadRawBars rawBarLoader,
                               FuncLoadAdjFactors fctLoader,
                               FuncLoadRawTicks tickLoader = NULL) {
        _ext_fnl_bar_loader = fnlBarLoader;
        _ext_raw_bar_loader = rawBarLoader;
        _ext_adj_fct_loader = fctLoader;
    }

    bool createExtParser(const char* id);
    bool createExtExecuter(const char* id);

    uint32_t createCtaContext(const char* name, int32_t slippage);

    CtaContextPtr getCtaContext(uint32_t id);
    WtEngine* getEngine() { return _engine; }

    const char* get_raw_stdcode(const char* stdCode);

    //////////////////////////////////////////////////////////////////////////
    // ILogHandler
public:
    virtual void handleLogAppend(WTSLogLevel ll, const char* msg) override;

    //////////////////////////////////////////////////////////////////////////
    //扩展Parser
public:
    void parser_init(const char* id);
    void parser_connect(const char* id);
    void parser_release(const char* id);
    void parser_disconnect(const char* id);
    void parser_subscribe(const char* id, const char* code);
    void parser_unsubscribe(const char* id, const char* code);

    void on_ext_parser_quote(const char* id, WTSTickStruct* curTick,
                             uint32_t uProcFlag);

    //////////////////////////////////////////////////////////////////////////
    //扩展Executer
public:
    void executer_set_position(const char* id, const char* stdCode,
                               double target);
    void executer_init(const char* id);

    //////////////////////////////////////////////////////////////////////////
    // ICtaEventListener
public:
    virtual void on_initialize_event() override {
        if (_cb_evt)
            _cb_evt(EVENT_ENGINE_INIT, 0, 0);
    }

    virtual void on_schedule_event(uint32_t uDate, uint32_t uTime) override {
        if (_cb_evt)
            _cb_evt(EVENT_ENGINE_SCHDL, uDate, uTime);
    }

    virtual void on_session_event(uint32_t uDate,
                                  bool isBegin = true) override {
        if (_cb_evt)
            _cb_evt(isBegin ? EVENT_SESSION_BEGIN : EVENT_SESSION_END, uDate,
                    0);
    }

public:
    void ctx_on_init(uint32_t id, EngineType eType = ET_CTA);
    void ctx_on_session_event(uint32_t id, uint32_t curTDate,
                              bool isBegin = true, EngineType eType = ET_CTA);
    void ctx_on_tick(uint32_t id, const char* stdCode, WTSTickData* newTick,
                     EngineType eType = ET_CTA);
    void ctx_on_calc(uint32_t id, uint32_t curDate, uint32_t curTime,
                     EngineType eType = ET_CTA);
    void ctx_on_bar(uint32_t id, const char* stdCode, const char* period,
                    WTSBarStruct* newBar, EngineType eType = ET_CTA);
    void ctx_on_cond_triggered(uint32_t id, const char* stdCode, double target,
                               double price, const char* usertag,
                               EngineType eType = ET_CTA);

    bool addExeFactories(const char* folder);
    bool addCtaFactories(const char* folder);

private:
    bool initTraders(WTSVariant* cfgTrader);
    bool initParsers(WTSVariant* cfgParser);
    bool initExecuters(WTSVariant* cfgExecuter);
    bool initDataMgr();
    bool initEvtNotifier();
    bool initCtaStrategies();
    bool initActionPolicy();

    bool initEngine();

private:
    FuncStraInitCallback _cb_cta_init;
    FuncSessionEvtCallback _cb_cta_sessevt;
    FuncStraTickCallback _cb_cta_tick;
    FuncStraCalcCallback _cb_cta_calc;
    FuncStraBarCallback _cb_cta_bar;
    FuncStraCondTriggerCallback _cb_cta_cond_trigger;

    FuncEventCallback _cb_evt;

    FuncParserEvtCallback _cb_parser_evt;
    FuncParserSubCallback _cb_parser_sub;

    FuncExecCmdCallback _cb_exec_cmd;
    FuncExecInitCallback _cb_exec_init;

    WTSVariant* _config;
    TraderAdapterMgr _traders;
    ParserAdapterMgr _parsers;
    WtExecuterFactory _exe_factory;

    WtCtaEngine _cta_engine;
    WtEngine* _engine;

    WtDataStorage* _data_store;

    WtDtMgr _data_mgr;

    WTSBaseDataMgr _bd_mgr;
    WTSHotMgr _hot_mgr;
    EventNotifier _notifier;

    CtaStrategyMgr _cta_mgr;
    ActionPolicyMgr _act_policy;

    bool _is_hft;
    bool _is_sel;

    FuncLoadFnlBars _ext_fnl_bar_loader;
    FuncLoadRawBars _ext_raw_bar_loader;
    FuncLoadAdjFactors _ext_adj_fct_loader;

    void* _feed_obj;
    FuncReadBars _feeder_bars;
    FuncReadFactors _feeder_fcts;
    StdUniqueMutex _feed_mtx;
};
